﻿Imports System.Runtime.InteropServices

Public Class DesktopEmbed
    <DllImport("user32.dll")>
    Private Shared Function FindWindow(lpClassName As String, lpWindowName As String) As IntPtr
    End Function

    <DllImport("user32.dll")>
    Private Shared Function FindWindowEx(parentHandle As IntPtr, childAfter As IntPtr, lclassName As String, windowTitle As String) As IntPtr
    End Function

    <DllImport("user32.dll")>
    Private Shared Function SendMessage(hWnd As IntPtr, Msg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll")>
    Private Shared Function GetParent(hWnd As IntPtr) As IntPtr
    End Function

    <DllImport("user32.dll")>
    Private Shared Function SetParent(hWndChild As IntPtr, hWndNewParent As IntPtr) As IntPtr
    End Function

    Private Const WM_COMMAND As Integer = &H111

    Public Shared OriginalParent As IntPtr

    Public Shared Sub EmbedToDesktop(frm As Form)
        ' 1. 找 Progman
        Dim progman = FindWindow("Progman", Nothing)

        ' 2. 向 Progman 发送消息，让它生成 WorkerW 窗口
        SendMessage(progman, WM_COMMAND, CType(&H3EF, IntPtr), IntPtr.Zero)
        Threading.Thread.Sleep(100)

        ' 3. 找到 WorkerW（桌面图标背后的窗口）
        Dim workerw As IntPtr = IntPtr.Zero
        Dim hWndWorkerW As IntPtr = FindWindowEx(IntPtr.Zero, IntPtr.Zero, "WorkerW", Nothing)
        While hWndWorkerW <> IntPtr.Zero
            Dim hView As IntPtr = FindWindowEx(hWndWorkerW, IntPtr.Zero, "SHELLDLL_DefView", Nothing)
            If hView = IntPtr.Zero Then
                workerw = hWndWorkerW
                Exit While
            End If
            hWndWorkerW = FindWindowEx(IntPtr.Zero, hWndWorkerW, "WorkerW", Nothing)
        End While

        ' 4. 保存原父窗口
        OriginalParent = GetParent(frm.Handle)
        ' 5. 挂到 WorkerW
        SetParent(frm.Handle, workerw)
    End Sub

    Public Shared Sub RestoreParent(frm As Form)
        If OriginalParent <> IntPtr.Zero Then
            SetParent(frm.Handle, OriginalParent)
        Else
            SetParent(frm.Handle, IntPtr.Zero)
        End If
    End Sub
End Class
